import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;

import model.NoSuchDirectoryException;
import model.cnf.CNF;
import model.cnf.FileCNF;
import model.preprocessor.PreProcessorFactory;
import model.session.CNFUse;
import model.session.ExecutionStatus;
import model.session.PreprocessorExecutionBlock;
import model.session.Session;
import model.solver.SolverFactory;

import org.junit.Before;
import org.junit.Test;

import controller.preprocessor.PreProcessor;

/**
 * 
 */

/**
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 *         igsat 2010
 * 
 */
public class TestSession {
	private String				cnflonguepath	= "./tstcnf/longue.cnf";
	private String				cnfsatpath		= "./tstcnf/sat.cnf";
	private String				cnfunsatpath	= "./tstcnf/unsat.cnf";
	private String				cnfcourpath		= "./tstcnf/cour.cnf";
	private String				cnfcourtepath	= "./tstcnf/courte.cnf";
	private String				out				= "./cnf/newcnf.cnf";
	private String				out2			= "./cnf/newcnf2.cnf";

	private File				dirpreproc		= new File("./preproc");
	private File				dirsolveur		= new File("./solveur");

	private PreProcessorFactory	preprocfactory	= new PreProcessorFactory(dirpreproc);
	private SolverFactory		solverfactory	= new SolverFactory(dirsolveur);

	Session						session;
	CNFUse						cnfuse;

	public CNFUse openCNFUse(String name) {

		CNF cnf = null;
		try
		{
			cnf = new FileCNF(name);
		} catch (IOException e)
		{
			e.printStackTrace();
			fail("problem loading cnf");
		}

		return new CNFUse(cnf);
	}

	public PreprocessorExecutionBlock createPreprocbloc(CNFUse cnf) {

		PreprocessorExecutionBlock block = null;
		PreProcessor preproc = null;
		try
		{
			preproc = preprocfactory.createRevivalPreProcessor();
		} catch (NoSuchDirectoryException e)
		{
			e.printStackTrace();
			fail("problem creating preproc");
		}

		block = new PreprocessorExecutionBlock(cnf, ExecutionStatus.FINISH, preproc, null);

		return block;
	}

	@Before
	public void setUp() {
		cnfuse = openCNFUse(cnfcourpath);
		session = new Session(cnfuse);
	}

	@Test
	public void testContainsCNFUse() {
		assertTrue("session doesn't contain the first cnf", session.containsCNFUse(cnfuse));

		CNFUse deux = openCNFUse(cnfcourtepath);

		assertFalse("session contains cnf that it is not supposed to", session.containsCNFUse(deux));

		cnfuse.addPreproc(createPreprocbloc(cnfuse), deux);

		assertTrue("session doesn't contain cnf that it is supposed to", session.containsCNFUse(cnfuse));
		assertTrue("session doesn't contain cnf that it is supposed to", session.containsCNFUse(deux));
	}

	@Test
	public void testContainsCNFUseWithNull() {
		CNFUse deux = openCNFUse(cnfcourtepath);

		cnfuse.addPreproc(createPreprocbloc(cnfuse), null);
		cnfuse.addPreproc(createPreprocbloc(cnfuse), deux);

		assertTrue("session doesn't contain cnf that it is supposed to", session.containsCNFUse(cnfuse));
		assertTrue("session doesn't contain cnf that it is supposed to", session.containsCNFUse(deux));

		CNFUse trois = openCNFUse(cnfsatpath);

		deux.addPreproc(createPreprocbloc(deux), trois);

		assertTrue("session doesn't contain cnf that it is supposed to", session.containsCNFUse(cnfuse));
		assertTrue("session doesn't contain cnf that it is supposed to", session.containsCNFUse(deux));
		assertTrue("session doesn't contain cnf that it is supposed to", session.containsCNFUse(trois));
	}

	@Test
	public void testContainsPreproc() {
		CNFUse deux = openCNFUse(cnfcourtepath);

		PreprocessorExecutionBlock preproc = createPreprocbloc(cnfuse);
		cnfuse.addPreproc(preproc, deux);

		assertEquals("session doesn't contain preproc that it is supposed to", session.containsPreprocessor(preproc), cnfuse);

		CNFUse trois = openCNFUse(cnfsatpath);

		PreprocessorExecutionBlock preproc2 = createPreprocbloc(deux);
		deux.addPreproc(preproc2, trois);

		assertEquals("session doesn't contain preproc that it is supposed to", session.containsPreprocessor(preproc), cnfuse);
		assertEquals("session doesn't contain preproc that it is supposed to", session.containsPreprocessor(preproc2), deux);

	}

	@Test
	public void testContainsPreprocWithNull() {
		CNFUse deux = openCNFUse(cnfcourtepath);
		CNFUse quatre = openCNFUse(cnfunsatpath);

		PreprocessorExecutionBlock preproc3 = createPreprocbloc(cnfuse);
		cnfuse.addPreproc(preproc3, null);


		PreprocessorExecutionBlock preproc = createPreprocbloc(cnfuse);
		cnfuse.addPreproc(preproc, deux);

		assertEquals("session doesn't contain preproc that it is supposed to", session.containsPreprocessor(preproc3), cnfuse);
		assertEquals("session doesn't contain preproc that it is supposed to", session.containsPreprocessor(preproc), cnfuse);

		CNFUse trois = openCNFUse(cnfsatpath);

		PreprocessorExecutionBlock preproc2 = createPreprocbloc(deux);
		deux.addPreproc(preproc2, trois);

		assertEquals("session doesn't contain preproc that it is supposed to", session.containsPreprocessor(preproc), cnfuse);
		assertEquals("session doesn't contain preproc that it is supposed to", session.containsPreprocessor(preproc2), deux);

	}


}
